home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / a_utils / _archvrs / unix / shar.lha / shar / shar.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-12-03  |  6.2 KB  |  248 lines

  1. /*
  2. **  SHAR
  3. **  Make a shell archive of a list of files.
  4. **
  5. **  Options:
  6. **    -b        Strip leading directories off names before packing
  7. **    -n #        Set number of this archive in a series
  8. **    -o foo        Output goes to file foo, not stdout
  9. **    -e #        Set ending archive number of series
  10. **    -t "See README"    Set instructions for when all archives are done
  11. */
  12. #include "shar.h"
  13. RCS("$Header: shar.c,v 1.18 87/03/18 14:10:21 rs Exp $")
  14.  
  15.  
  16. /*
  17. **  This prolog is output before the archive.
  18. */
  19. static char     *Prolog[] = {
  20.   "! /bin/sh",
  21.   " This is a shell archive.  Remove anything before this line, then unpack",
  22.   " it by saving it into a file and typing \"sh file\".  To overwrite existing",
  23.   " files, type \"sh file -c\".  You can also feed this as standard input via",
  24.   " unshar, or by typing \"sh <file\", e.g..  If this archive is complete, you",
  25.   " will see the following message at the end:",
  26.   NULL
  27. };
  28.  
  29.  
  30. /*
  31. **  Package up one file or directory.
  32. */
  33. static void
  34. shar(file, Basename)
  35.     char        *file;
  36.     int             Basename;
  37. {
  38.     register char    *s;
  39.     register char    *Name;
  40.     register int     Bads;
  41.     register int     Lastchar;
  42.     register off_t     Size;
  43.     char         buf[BUFSIZ];
  44.  
  45.     /* Just in case. */
  46.     if (EQ(file, ".") || EQ(file, ".."))
  47.     return;
  48.  
  49.     Size = Fsize(file);
  50.     Name =  Basename && (Name = RDX(file, '/')) ? Name + 1 : file;
  51.  
  52.     /* Making a directory? */
  53.     if (Ftype(file) == F_DIR) {
  54.     printf("if test ! -d %s ; then\n", Name);
  55.     printf("    echo shar: Creating directory \\\"%s\\\"\n", Name);
  56.     printf("    mkdir %s\n", Name);
  57.     printf("fi\n");
  58.     }
  59.     else {
  60.     if (freopen(file, "r", stdin) == NULL) {
  61.         fprintf(stderr, "Can't open %s, %s\n", file, Ermsg(errno));
  62.         exit(1);
  63.     }
  64.  
  65.     /* Emit the per-file prolog. */
  66.     printf("if test -f %s -a \"${1}\" != \"-c\" ; then \n", Name);
  67.     printf("  echo shar: Will not over-write existing file \\\"%s\\\"\n",
  68.            Name);
  69.     printf("else\n");
  70.     printf("echo shar: Extracting \\\"%s\\\" \\(%ld character%s\\)\n",
  71.            Name, (long)Size, Size > 1 ? "s" : "");
  72.     printf("sed \"s/^X//\" >%s <<'END_OF_%s'\n", Name, Name);
  73.  
  74.     /* Output the file contents. */
  75.     for (Bads = 0, Lastchar = '\n'; fgets(buf, BUFSIZ, stdin); ) {
  76.         printf("X");
  77.         if (buf[0]) {
  78.         for (s = buf; *s; s++) {
  79.             if (BADCHAR(*s))
  80.             Bads++;
  81.             (void)putchar(*s);
  82.         }
  83.         Lastchar = s[-1];
  84.         }
  85.         else
  86.         Lastchar = 'X';
  87.     }
  88.  
  89.     /* Tell about missing \n and control characters. */
  90.     if (Lastchar != '\n')
  91.         (void)putchar('\n');
  92.     printf("END_OF_%s\n", Name);
  93.     if (Lastchar != '\n') {
  94.         printf("echo shar: Missing newline added to \\\"%s\\\"\n", Name);
  95.         fprintf(stderr, "Missing newline added to \"%s\"\n", Name);
  96.     }
  97.     if (Bads) {
  98.         printf(
  99.     "echo shar: %d control character%s may be missing from \\\"%s\\\"\n",
  100.            Bads, Bads > 1 ? "s" : "", Name);
  101.         fprintf(stderr, "Found %d control char%s in \"%s\"\n",
  102.             Bads, Bads > 1 ? "s" : "", Name);
  103.     }
  104.  
  105.     /* Output size check. */
  106.     printf("if test %ld -ne `wc -c <%s`; then\n", (long)Size, Name);
  107.     printf("    echo shar: \\\"%s\\\" unpacked with wrong size!\n", Name);
  108.     printf("fi\n");
  109.  
  110.     /* Executable? */
  111.     if (Fexecute(file))
  112.         printf("chmod +x %s\n", Name);
  113.  
  114.     printf("# end of overwriting check\nfi\n");
  115.     }
  116. }
  117.  
  118.  
  119. main(ac, av)
  120.     int             ac;
  121.     register char    *av[];
  122. {
  123.     register char    *Trailer;
  124.     register char    *p;
  125.     register int     i;
  126.     register int     length;
  127.     register int     Oops;
  128.     register int     Knum;
  129.     register int     Kmax;
  130.     time_t         clock;
  131.     int             Basename;
  132.  
  133.     /* Parse JCL. */
  134.     Basename = 0;
  135.     Knum = 0;
  136.     Kmax = 0;
  137.     Trailer = NULL;
  138.     for (Oops = 0; (i = getopt(ac, av, "be:n:o:t:")) != EOF; )
  139.     switch (i) {
  140.         default:
  141.         Oops++;
  142.         break;
  143.         case 'b':
  144.         Basename++;
  145.         break;
  146.         case 'e':
  147.         Kmax = atoi(optarg);
  148.         break;
  149.         case 'n':
  150.         Knum = atoi(optarg);
  151.         break;
  152.         case 'o':
  153.         if (freopen(optarg, "w", stdout) == NULL) {
  154.             fprintf(stderr, "Can't open %s for output, %s.\n",
  155.                 optarg, Ermsg(errno));
  156.             Oops++;
  157.         }
  158.         break;
  159.         case 't':
  160.         Trailer = optarg;
  161.         break;
  162.     }
  163.     av += optind;
  164.     if (*av == NULL) {
  165.     fprintf(stderr, "No input files\n");
  166.     Oops++;
  167.     }
  168.     if (Oops) {
  169.     fprintf(stderr, "USAGE: shar [-b] [-o:] [-n:e:t:] file... >SHAR\n");
  170.     exit(1);
  171.     }
  172.  
  173.     /* Everything readable and reasonably-named? */
  174.     for (Oops = 0, i = 0; p = av[i]; i++)
  175.     if (freopen(p, "r", stdin) == NULL) {
  176.         fprintf(stderr, "Can't read %s, %s.\n", p, Ermsg(errno));
  177.         Oops++;
  178.     }
  179.     else
  180.         for (; *p; p++)
  181.         if (!isascii(*p)
  182.          || (!isalnum(*p) && IDX(OK_CHARS, *p) == NULL)) {
  183.             fprintf(stderr, "Bad character '%c' in '%s'.\n", *p, av[i]);
  184.             Oops++;
  185.         }
  186.     if (Oops)
  187.     exit(2);
  188.  
  189.     /* Prolog. */
  190.     for (i = 0; p = Prolog[i]; i++)
  191.     printf("#%s\n", p);
  192.     if (Knum && Kmax)
  193.     printf("#\t\t\"End of archive %d (of %d).\"\n", Knum, Kmax);
  194.     else
  195.         printf("#\t\t\"End of shell archive.\"\n");
  196.     printf("# Contents: ");
  197.     for (length = 12, i = 0; p = av[i++]; length += strlen(p) + 1)
  198.     if (length + strlen(p) + 1 < WIDTH)
  199.         printf(" %s", p);
  200.     else {
  201.         printf("\n#   %s", p);
  202.         length = 4;
  203.     }
  204.     printf("\n");
  205.     clock = time((time_t *)NULL);
  206.     printf("# Wrapped by %s@%s on %s", User(), Host(), ctime(&clock));
  207.     printf("PATH=/bin:/usr/bin:/usr/ucb ; export PATH\n");
  208.  
  209.     /* Do it. */
  210.     while (*av)
  211.     shar(*av++, Basename);
  212.  
  213.     /* Epilog. */
  214.     if (Knum && Kmax) {
  215.     printf("echo shar: End of archive %d \\(of %d\\).\n", Knum, Kmax);
  216.     printf("cp /dev/null ark%disdone\n", Knum);
  217.     printf("MISSING=\"\"\n");
  218.     printf("for I in");
  219.     for (i = 0; i < Kmax; i++)
  220.         printf(" %d", i + 1);
  221.     printf(" ; do\n");
  222.     printf("    if test ! -f ark${I}isdone ; then\n");
  223.     printf("\tMISSING=\"${MISSING} ${I}\"\n");
  224.     printf("    fi\n");
  225.     printf("done\n");
  226.     printf("if test \"${MISSING}\" = \"\" ; then\n");
  227.     if (Kmax == 2)
  228.         printf("    echo You have unpacked both archives.\n");
  229.     else
  230.         printf("    echo You have unpacked all %d archives.\n", Kmax);
  231.     if (Trailer && *Trailer)
  232.         printf("    echo \"%s\"\n", Trailer);
  233.     printf("    rm -f ark[1-9]isdone%s\n",
  234.            Kmax >= 9 ? " ark[1-9][0-9]isdone" : "");
  235.     printf("else\n");
  236.     printf("    echo You still need to unpack the following archives:\n");
  237.     printf("    echo \"        \" ${MISSING}\n");
  238.     printf("fi\n");
  239.     printf("##  End of shell archive.\n");
  240.     }
  241.     else
  242.         printf("echo shar: End of shell archive.\n");
  243.  
  244.     printf("exit 0\n");
  245.  
  246.     exit(0);
  247. }
  248.